<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // 1.递归： 在函数里面自己调用自己；递归的实质是能够把一个大问题分解成比它小点的问题，
      // 然后我们拿到了小问题的解，就可以用小问题的解去构造大问题的解 ---  可能有栈溢出的问题，需要合适的退出条件
      // 我们常用的深拷贝，就是递归最常见的用法
      // 2.之前自己写过将平铺数据结构转换为树形结构，就是添加children, 核心思想就是，当传递的函数参数pid和循环
      // 数组的item.pid相等的时候，就将item添加到返回数组里面去，并且将当前item.id再次当做父的pid传递递归函数使用，
      // 最后将返回值放到children属性里面去
      // 3.还写过一个 将树形结构转换为平铺结构，核心思想就是新建一个数组，将原数组每一项添加到新数组里面去，去掉对象里面的
      // children，然后将iten.children再次当做递归函数的参数，再次去平铺结构

      // 案例一：
      var arr = [
        { id: "29", pid: "", name: "总裁办" },
        { id: "2c", pid: "", name: "财务部" },
        { id: "2d", pid: "2c", name: "财务核算部" },
        { id: "2f", pid: "2c", name: "薪资管理部" },
        { id: "d2", pid: "", name: "技术部" },
        { id: "d3", pid: "d2", name: "Java研发部" },
        { id: "d31", pid: "d3", name: "Java研发部" },
      ];

      // 接受两个参数， 1：平铺数组， 2：那种数据格式是一级菜单
      function treeToList(arr, pid) {
        // 递归第二次loop函数  item = { id: '2c', pid: '', name: '财务部' },
        function loop(pid) {
          let res = [];
          arr.forEach((item) => {
            if (item.pid === pid) {
              item.children = loop(item.id);
              res.push(item);
            }
          });
          return res;
        }

        return loop(pid);
      }

      const tree = treeToList(arr, "");

      // 案例二：
      // 树形结构转换为数组
      const arr = [
        { id: "29", pid: "", name: "总裁办", children: [] },
        {
          id: "2c",
          pid: "",
          name: "财务部",
          children: [
            { id: "2d", pid: "2c", name: "财务核算部", children: [] },
            { id: "2f", pid: "2c", name: "薪资管理部", children: [] },
          ],
        },
        {
          id: "d2",
          pid: "",
          name: "技术部",
          children: [
            {
              id: "d3",
              pid: "d2",
              name: "Java研发部",
              children: [
                { id: "d31", pid: "d3", name: "Java研发部", children: [] },
              ],
            },
          ],
        },
      ];

      // 树形结构转平铺
      const treeToList = (tree) => {
        let res = [];
        function flat(arr) {
          if (arr && arr.length > 0) {
            arr.forEach((item) => {
              res.push({ id: item.id, pid: item.pid, name: item.name });
              flat(item.children);
            });
          }
        }

        flat(tree);
        return res;
      };

      const list = treeToList(arr);

      // 案例三：
      // 写一个函数，传递一个数组和一个id，根据id得到对应对的名称
      var data = [
        {
          id: 1,
          name: "家电",
          goods: [
            { id: 11, name: "冰箱", goods: [{ id: 111, name: "海尔" }] },
            { id: 12, name: "洗衣机" },
          ],
        },
        { id: 2, name: "服饰" },
      ];

      var o = {};
      function getID(json, id) {
        json.forEach(function (item) {
          if (item.id == id) {
            o = item;
          } else if (item.goods && item.goods.length > 0) {
            o = getID(item.goods, id);
          }
        });
        return o;
      }

      console.log(getID(data, 1));
      console.log(getID(data, 2));
      console.log(getID(data, 11));
      console.log(getID(data, 12));
      console.log(getID(data, 111));

      // 案例四
      // 给定一个数组，求出里面所有name的集合
      let data = [
        {
          name: "所有物品",
          children: [
            {
              name: "水果",
              children: [
                {
                  name: "苹果",
                  children: [{ name: "青苹果" }, { name: "红苹果" }],
                },
              ],
            },
            {
              name: "主食",
              children: [
                {
                  name: "米饭",
                  children: [{ name: "北方米饭" }, { name: "南方米饭" }],
                },
              ],
            },
            {
              name: "生活用品",
              children: [
                {
                  name: "电脑类",
                  children: [{ name: "联想电脑" }, { name: "苹果电脑" }],
                },
                {
                  name: "工具类",
                  children: [{ name: "锄头" }, { name: "锤子" }],
                },
                {
                  name: "生活用品",
                  children: [{ name: "洗发水" }, { name: "沐浴露" }],
                },
              ],
            },
          ],
        },
      ];

      function fn(data, arr = []) {
        data.forEach((item) => {
          if (item.children && item.children.length > 0) {
            fn(item.children, arr);
          } else {
            arr.push(item.name);
          }
        });
        return arr;
      }

      fn(data);
    </script>
  </body>
</html>
